


# include <stdlib.h>
# include "pila.h"
# define TAM 100
/* ********************************************************************
 *                          Declaracion de Tipo                    
 **********************************************************************/

struct _pila{
       
       void** datos;
       size_t tamanio;
       size_t cantidad;
       
};


/**********************************************************************/
/*                          IMPLEMENTACION                            */       
/**********************************************************************/

pila_t* pila_crear (){
        
        pila_t *nueva_pila = malloc (sizeof(pila_t));
        
        if (nueva_pila == NULL)
           return NULL;
        
        nueva_pila->datos = malloc (TAM*sizeof(void*));
        if (nueva_pila->datos == NULL){
		  free (nueva_pila);
		  return NULL;
	  }	
        
        nueva_pila->tamanio = TAM;
        nueva_pila->cantidad = 0;  
        
        return nueva_pila;
} 

bool pila_redimensionar (pila_t *pila, size_t tam){
	
	void** nuevos_datos = realloc (pila->datos,tam*sizeof (void*));
	if (nuevos_datos == NULL) return false;
	
	pila->datos = nuevos_datos;
	pila->tamanio = tam;
	
	return true;
	
}

bool pila_esta_vacia (const pila_t *pila){
     
     if (pila->cantidad == 0)
        return true;
     
     return false;
}

bool pila_llena (const pila_t *pila){
	
	if (pila->tamanio == pila->cantidad) 
		return true;
	
	return false;
}

void* pila_ver_tope (const pila_t *pila){
     
	if (pila->cantidad == 0) 
		return NULL;
	
	return pila->datos[pila->cantidad-1];     
     
}

bool pila_apilar (pila_t *pila, void* elem){
	
	if (pila_llena (pila)){ 
		bool result = pila_redimensionar (pila,(pila->tamanio*2));
		if (!result) return false;
	}
	
	pila->datos[pila->cantidad] = elem;
	pila->cantidad++;	
	
	return true;	
	
}

void* pila_desapilar (pila_t *pila){
      
	void* dato = pila_ver_tope (pila);
	pila->cantidad--;
     
	if (pila->cantidad == (pila->tamanio/3) && pila->tamanio > TAM)
		pila_redimensionar (pila,(pila->tamanio/2));
		
	return dato;
     
}

void pila_destruir (pila_t *pila){
      
	free (pila->datos);
	free (pila);
           
}
